<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>Merge Selector Lab</title>
        <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
        <script src="https://d3js.org/d3.v7.min.js"></script>
        <style>
            #trainButton {
                width: 100%;
                position: relative;
                overflow: hidden;
                color: white;
                background-color: #007bff;
                border: none;
            }
            #trainButton .progress-fill {
                position: absolute;
                top: 0;
                left: 0;
                height: 100%;
                background-color: rgba(255, 255, 255, 0.3); /* Transparent overlay */
                width: 0;
                transition: width 0.1s linear; /* Smooth progress */
            }
            #downloadButton {
                display: none;
                margin-top: 1rem;
                width: 100%;
            }
        </style>
    </head>
    <body>
        <div class="container-fluid">
            <form id="param-form" class="p-3">
                <div class="row">
                    <div class="form-group col-md-4">
                        <label for="minPartSize">Min part size:</label>
                        <input type="text" class="form-control form-control-sm" id="minPartSize" placeholder="Minimum size" value="64KB">
                    </div>
                    <div class="form-group col-md-4">
                        <label for="maxPartSize">Max part size:</label>
                        <input type="text" class="form-control form-control-sm" id="maxPartSize" placeholder="Maximum size" value="256GB">
                    </div>
                    <div class="form-group col-md-4">
                        <label for="maxWorkers">Max workers:</label>
                        <input type="text" class="form-control form-control-sm" id="maxWorkers" placeholder="Maximum workers" value="32768">
                    </div>
                </div>
                <div class="row">
                    <div class="form-group col-md-4">
                        <label for="partsStep">Part size step:</label>
                        <input type="text" class="form-control form-control-sm" id="partsStep" placeholder="Power of 2 exponent" value="0.25">
                    </div>
                    <div class="form-group col-md-4">
                        <label for="workersStep">Workers step:</label>
                        <input type="text" class="form-control form-control-sm" id="workersStep" placeholder="Power of 2 exponent" value="0.25">
                    </div>
                </div>
                <div class="row mt-3">
                    <div class="col">
                        <button type="button" class="btn btn-primary" id="trainButton">
                            <span id="trainButtonText">Train</span>
                            <div class="progress-fill"></div>
                        </button>
                        <button type="button" class="btn btn-success" id="downloadButton">Download</button>
                    </div>
                </div>
            </form>
        </div>

        <script type="module">
            import { MergeTree } from './MergeTree.js';
            import { SimulationContainer } from './SimulationContainer.js';
            import { sequenceInserter } from './sequenceInserter.js';
            import { floatLayerMerges } from './floatLayerMerges.js';
            import { subgradientMethod } from './gradientDescent.js';
            import { mergeModel } from './mergeModel.js';
            import { ModelSolver } from './ModelSolver.js';
            import { delayMs, parseHumanReadableSize } from './util.js';

            function readSize(name) {
                return parseHumanReadableSize(document.getElementById(name).value);
            }

            function readParams() {
                let params = {
                    minPartSize: readSize('minPartSize'),
                    maxPartSize: readSize('maxPartSize'),
                    maxWorkers: readSize('maxWorkers'),
                    partsStep: readSize('partsStep'),
                    workersStep: readSize('workersStep'),
                };
                console.log("PARAMS", params);
                return params;
            }

            document.getElementById('trainButton').addEventListener('click', async () => {
                const trainButton = document.getElementById('trainButton');
                const progressFill = trainButton.querySelector('.progress-fill');
                const trainButtonText = document.getElementById('trainButtonText');
                const downloadButton = document.getElementById('downloadButton');

                trainButton.disabled = true;
                trainButtonText.textContent = 'Training...';
                progressFill.style.width = '0%';
                downloadButton.style.display = 'none';

                const { minPartSize, maxPartSize, maxWorkers, partsStep, workersStep } = readParams();

                let solver = new ModelSolver(mergeModel);
                await solver.train(minPartSize, maxPartSize, maxWorkers, partsStep, workersStep, subgradientMethod,
                    async function onProgress({progress, runs_done, runs_total}) {
                        // Update progress bar (button background)
                        progressFill.style.width = `${progress}%`;
                        trainButtonText.textContent = `Training: ${progress}% — ${runs_done}/${runs_total}`;
                        await delayMs(1);
                    });
                console.log(solver.data);

                trainButtonText.textContent = 'Train Again';
                trainButton.disabled = false;

                // Show the download button
                downloadButton.style.display = 'block';

                // Set up download functionality
                downloadButton.addEventListener('click', () => {
                    const data = solver.serializeData();
                    const blob = new Blob([data], { type: 'application/json' });
                    const url = URL.createObjectURL(blob);
                    const link = document.createElement('a');
                    link.href = url;
                    let params = [
                        document.getElementById('minPartSize').value,
                        document.getElementById('maxPartSize').value,
                        document.getElementById('maxWorkers').value,
                        'x' + (1.0 / +document.getElementById('partsStep').value),
                        'x' + (1.0 / +document.getElementById('workersStep').value),
                    ];
                    link.download = `solver-${params.join('_')}.json`;
                    link.click();
                    URL.revokeObjectURL(url);
                }, { once: true });
            });
        </script>
    </body>
</html>
